# 
# Copyright (c) 2015-2020 CNRS INRIA
# Copyright (c) 2015 Wandercraft, 86 rue de Paris 91400 Orsay, France.
#

# --- MACROS --- #
MACRO(SYMLINK_AND_INSTALL_HEADERS HEADERS SUBPATH)
  FOREACH(header ${HEADERS})
    GET_FILENAME_COMPONENT(headerName ${header} NAME)
    GET_FILENAME_COMPONENT(headerPath ${header} PATH)
    EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E ${LINK}
      ${CMAKE_CURRENT_SOURCE_DIR}/${header}
      ${${PROJECT_NAME}_BINARY_DIR}/include/${PROJECT_NAME}/${SUBPATH}/${header})

    INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${header}
      DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}/${SUBPATH}/${headerPath}
            PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE)
  ENDFOREACH(header)
ENDMACRO(SYMLINK_AND_INSTALL_HEADERS HEADERS SUBPATH)

FUNCTION(REMOVE_PATH_FROM_LIST list_name path_name dest_list)
  SET(list_name_)
  FOREACH(header ${list_name})
    STRING(REGEX REPLACE "${path_name}" "" header ${header}) 
    LIST(APPEND list_name_ ${header})
  ENDFOREACH(header ${list_name_})
  SET(${dest_list} ${list_name_} PARENT_SCOPE)
ENDFUNCTION(REMOVE_PATH_FROM_LIST)

# --- PYTHON TARGET --- #
SET(PYWRAP ${PROJECT_NAME}_pywrap)
SET(PYWRAP ${PYWRAP} PARENT_SCOPE)

FILE(GLOB_RECURSE ${PROJECT_NAME}_PYTHON_HEADERS
     ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp 
     ) 

FILE(GLOB_RECURSE ${PROJECT_NAME}_PYTHON_SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp 
     ) 

# Parser for Python model
LIST(APPEND ${PROJECT_NAME}_PYTHON_HEADERS
  parsers/python.hpp
  )
SET(${PROJECT_NAME}_PARSER_PYTHON_HEADERS
  parsers/python.hpp
  )

LIST(APPEND ${PROJECT_NAME}_PYTHON_SOURCES
  parsers/python/model.cpp
  )

REMOVE_PATH_FROM_LIST("${${PROJECT_NAME}_PYTHON_HEADERS}" "${CMAKE_CURRENT_SOURCE_DIR}/" ${PROJECT_NAME}_PYTHON_HEADERS)
REMOVE_PATH_FROM_LIST("${${PROJECT_NAME}_PYTHON_SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/" ${PROJECT_NAME}_PYTHON_SOURCES)

# Python exposition of FCL
IF(NOT BUILD_WITH_HPP_FCL_PYTHON_BINDINGS)
  LIST(REMOVE_ITEM ${PROJECT_NAME}_PYTHON_HEADERS
    multibody/fcl/transform.hpp
    )
  LIST(REMOVE_ITEM ${PROJECT_NAME}_PYTHON_SOURCES
    multibody/fcl/expose-fcl.cpp
    )
ENDIF(NOT BUILD_WITH_HPP_FCL_PYTHON_BINDINGS)

LIST(APPEND HEADERS ${${PROJECT_NAME}_PYTHON_HEADERS})

# Headers of the Python bindings
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python/spatial")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python/multibody")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python/multibody/joint")
IF(BUILD_WITH_HPP_FCL_PYTHON_BINDINGS)
  MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python/multibody/fcl")
ENDIF(BUILD_WITH_HPP_FCL_PYTHON_BINDINGS)
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python/parsers")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python/serialization")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python/algorithm")
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/bindings/python/utils")
SYMLINK_AND_INSTALL_HEADERS("${${PROJECT_NAME}_PYTHON_HEADERS}" "bindings/python")

# Headers of the Python parser
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/parsers/python")
SYMLINK_AND_INSTALL_HEADERS("${${PROJECT_NAME}_PARSER_PYTHON_HEADERS}" "")

# --- COMPILE WRAPPER
MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/bindings/python/${PROJECT_NAME}")
SET(${PYWRAP}_SOURCES ${${PROJECT_NAME}_PYTHON_SOURCES})
SET(${PYWRAP}_HEADERS ${${PROJECT_NAME}_PYTHON_HEADERS})

IF(BUILD_PYTHON_INTERFACE)
  INCLUDE_DIRECTORIES(SYSTEM ${PYTHON_INCLUDE_DIRS}) 
  ADD_CUSTOM_TARGET(python)
  SET_TARGET_PROPERTIES(python PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD True)

  SET(PKG_CONFIG_PYWRAP_REQUIRES "eigenpy >= 2.2.0")
  ADD_LIBRARY(${PYWRAP} SHARED ${${PYWRAP}_SOURCES} ${${PYWRAP}_HEADERS})
  ADD_DEPENDENCIES(python ${PYWRAP})
  
  SET_TARGET_PROPERTIES(${PYWRAP} PROPERTIES PREFIX "") # Remove lib prefix for the target

  # Do not report:
  #  -Wconversion as the BOOST_PYTHON_FUNCTION_OVERLOADS implicitly converts.
  #  -Wcomment as latex equations have multi-line comments.
  TARGET_COMPILE_OPTIONS(${PYWRAP} PRIVATE -Wno-conversion -Wno-comment)

  SET_TARGET_PROPERTIES(${PYWRAP} PROPERTIES VERSION ${PROJECT_VERSION})
  IF(BUILD_WITH_COMMIT_VERSION)
    TAG_LIBRARY_VERSION(${PYWRAP})
  ENDIF(BUILD_WITH_COMMIT_VERSION)
  ADD_HEADER_GROUP(${PYWRAP}_HEADERS)
  ADD_SOURCE_GROUP(${PYWRAP}_SOURCES)

  TARGET_LINK_LIBRARIES(${PYWRAP} PUBLIC ${PROJECT_NAME} eigenpy::eigenpy)
  TARGET_LINK_BOOST_PYTHON(${PYWRAP} PUBLIC)
  IF(BUILD_WITH_HPP_FCL_PYTHON_BINDINGS)
    TARGET_COMPILE_DEFINITIONS(${PYWRAP} PRIVATE -DPINOCCHIO_WITH_HPP_FCL_PYTHON_BINDINGS)
  ENDIF(BUILD_WITH_HPP_FCL_PYTHON_BINDINGS)
  IF(WIN32)
    TARGET_COMPILE_DEFINITIONS(${PYWRAP} PRIVATE -DNOMINMAX)
    TARGET_LINK_LIBRARIES(${PYWRAP} PUBLIC ${PYTHON_LIBRARY})
  ENDIF(WIN32)

  IF(PINOCCHIO_SITELIB_ROOT)
    SET(${PYWRAP}_INSTALL_DIR ${PINOCCHIO_SITELIB_ROOT}/${PYTHON_SITELIB}/${PROJECT_NAME})
  ELSE()
    SET(${PYWRAP}_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/${PYTHON_SITELIB}/${PROJECT_NAME})
  ENDIF()

  SET_TARGET_PROPERTIES(${PYWRAP}
    PROPERTIES 
    PREFIX ""
    SUFFIX ${PYTHON_EXT_SUFFIX}
    OUTPUT_NAME "${PYWRAP}"
    LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bindings/python/${PROJECT_NAME}"
    )

  INSTALL(
    TARGETS ${PYWRAP} 
    EXPORT ${TARGETS_EXPORT_NAME}
    DESTINATION ${${PYWRAP}_INSTALL_DIR}
    )

  # --- INSTALL SCRIPTS 
  SET(PYTHON_FILES
    __init__.py
    deprecated.py
    deprecation.py
    utils.py
    robot_wrapper.py
    romeo_wrapper.py
    explog.py
    shortcuts.py
    )

  FOREACH(python ${PYTHON_FILES})
    PYTHON_BUILD(${PROJECT_NAME} ${python})
    INSTALL(FILES
      "${${PROJECT_NAME}_SOURCE_DIR}/bindings/python/pinocchio/${python}"
      DESTINATION ${${PYWRAP}_INSTALL_DIR})
  ENDFOREACH(python)

  # --- INSTALL VISUALIZATION SCRIPTS
  SET(PYTHON_VISUALIZE_FILES
    __init__.py
    base_visualizer.py
    gepetto_visualizer.py
    meshcat_visualizer.py
    panda3d_visualizer.py
    )

  FOREACH(python ${PYTHON_VISUALIZE_FILES})
    PYTHON_BUILD(${PROJECT_NAME}/visualize ${python})
    INSTALL(FILES
      "${${PROJECT_NAME}_SOURCE_DIR}/bindings/python/pinocchio/visualize/${python}"
      DESTINATION ${${PYWRAP}_INSTALL_DIR}/visualize)
  ENDFOREACH(python)

  # --- PACKAGING --- #

  # Format string
  SET(_PKG_CONFIG_PYWRAP_LIBDIR ${${PYWRAP}_INSTALL_DIR})
  SET(_PKG_CONFIG_PYWRAP_BINDIR ${${PYWRAP}_INSTALL_DIR})
  SET(_PKG_CONFIG_PYWRAP_CONFLICTS)
  SET(_PKG_CONFIG_PYWRAP_REQUIRES "${PROJECT_NAME}")
  FOREACH(dep ${PKG_CONFIG_PYWRAP_REQUIRES})
    SET(_PKG_CONFIG_PYWRAP_REQUIRES "${_PKG_CONFIG_PYWRAP_REQUIRES}, ${dep}")
  ENDFOREACH(dep ${PKG_CONFIG_PYWRAP_REQUIRES})

  SET(_PKG_CONFIG_PYWRAP_LIBS "-L\${libdir} -l${PYWRAP}")
  IF(APPLE)
    SET(_PKG_CONFIG_PYWRAP_LIBS "${_PKG_CONFIG_PYWRAP_LIBS} -Wl,-undefined,dynamic_lookup,${Boost_${UPPERCOMPONENT}_LIBRARY}")
  ELSE(APPLE)
    SET(_PKG_CONFIG_PYWRAP_LIBS "${_PKG_CONFIG_PYWRAP_LIBS} ${LIBINCL_KW}boost_python")
  ENDIF(APPLE)

  SET(_PKG_CONFIG_PYWRAP_CFLAGS "-I\${includedir} -I/usr/local/include")
  SET(_PKG_CONFIG_PYWRAP_CFLAGS "${_PKG_CONFIG_PYWRAP_CFLAGS} -I${PYTHON_INCLUDE_DIRS}")
  FOREACH(cflags ${CFLAGS_DEPENDENCIES})
    SET(_PKG_CONFIG_PYWRAP_CFLAGS "${_PKG_CONFIG_PYWRAP_CFLAGS} ${cflags}")
  ENDFOREACH(cflags ${CFLAGS_DEPENDENCIES})

  CONFIGURE_FILE(
     "${CMAKE_CURRENT_SOURCE_DIR}/pinocchiopy.pc.cmake"
     "${CMAKE_CURRENT_BINARY_DIR}/pinocchiopy.pc")

  INSTALL(
      FILES "${CMAKE_CURRENT_BINARY_DIR}/pinocchiopy.pc"
      DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
      PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE)
ENDIF(BUILD_PYTHON_INTERFACE)
